package com.adinnet.common.upload;


import com.adinnet.common.aliyunoss.AliyunOSSClientUtil;
import com.adinnet.common.utils.DateUtil;
import com.adinnet.common.utils.StringUtil;
import com.aliyun.oss.OSSClient;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

public class UploadUtils {
    private static final Logger log = LoggerFactory.getLogger(UploadUtils.class);

    /**
     * 阿里云oss文件上传
     * @param myfile
     * @return
     */
    public static String uploadFile(MultipartFile myfile) {
        OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
        String originalFilename = myfile.getOriginalFilename();
        Random random = new Random();
        String fileName = random.nextInt(10000) + System.currentTimeMillis()
                + originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
        log.info("上传开始{}", DateUtil.getCurrentTime());
        String md5key = AliyunOSSClientUtil.uploadObject2OSS(ossClient, myfile, AliyunOSSClientUtil.BACKET_NAME,
                AliyunOSSClientUtil.FOLDER, fileName);
        if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isEmpty(md5key)) {
            throw new RuntimeException("上传文件异常");
        }
        String filePaths = AliyunOSSClientUtil.getImgUrl(fileName);
        log.info("上传结束{},文件路径{}", DateUtil.getCurrentTime(),filePaths);
        return filePaths;
    }

    /**
     * 上传文件到服务器
     * @param img
     * @return
     */
    public static String uploadFileLinux(MultipartFile img){
        String realPath = UploadConfig.REAL_PATH;
        String fileName = img.getOriginalFilename();
        if (!"".equals(fileName)) {
            DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
            DateFormat dfT = new SimpleDateFormat("yyyyMMdd");
            Calendar calendar = Calendar.getInstance();
            realPath += "/" + dfT.format(calendar.getTime());

            fileName = df.format(calendar.getTime()) + ((int) (Math.random() * 9000) + 1000) + fileName.substring(fileName.lastIndexOf("."));
            File targetFile = new File(realPath);
            if (!targetFile.exists()) {
                targetFile.mkdirs();
            }
            //保存
            try {
                File upFile = new File(realPath, fileName);
                img.transferTo(upFile);
                return "/" + UploadConfig.VIRTUAL_PATH + "/" + dfT.format(calendar.getTime()) + "/" + fileName;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 删除文件，可以是文件或文件夹
     *
     * @param fileName
     *            要删除的文件名
     * @return 删除成功返回true，否则返回false
     */
    public static boolean delete(String fileName) {
        File file = new File(fileName);
        if (!file.exists()) {
            log.info("删除文件失败:" + fileName + "不存在！");
            return false;
        } else {
          /*  FileLog log=new FileLog();
            log.setFileUrl(fileName.substring(fileName.lastIndexOf(",")));
            log.setDoType(FileDoType.DELETE.getCode());
            fileLogDao.insertSelective(log);*/
            if (file.isFile())
                return deleteFile(fileName);
            else
                return deleteDirectory(fileName);

        }
    }


    /**
     * 删除单个文件
     *
     * @param fileName
     *            要删除的文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                log.info("删除单个文件" + fileName + "成功！");
                return true;
            } else {
                log.info("删除单个文件" + fileName + "失败！");
                return false;
            }
        } else {
            log.info("删除单个文件失败：" + fileName + "不存在！");
            return false;
        }
    }

    public static boolean batchDeleteFile(List<String> fileName) {
        if(CollectionUtils.isNotEmpty(fileName)){
            for (String url:fileName){
                String path = UploadConfig.REAL_PATH +url.substring(url.lastIndexOf("/"),url.length());
                deleteFile(path);
            }
        }
        return true;
    }
    /**
     * 删除目录及目录下的文件
     *
     * @param dir
     *            要删除的目录的文件路径
     * @return 目录删除成功返回true，否则返回false
     */
    public static boolean deleteDirectory(String dir) {
        // 如果dir不以文件分隔符结尾，自动添加文件分隔符
        if (!dir.endsWith(File.separator))
            dir = dir + File.separator;
        File dirFile = new File(dir);
        // 如果dir对应的文件不存在，或者不是一个目录，则退出
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
            log.info("删除目录失败：" + dir + "不存在！");
            return false;
        }
        boolean flag = true;
        // 删除文件夹中的所有文件包括子目录
        File[] files = dirFile.listFiles();
        if(files!=null&&files.length!=0) {
            for (int i = 0; i < files.length; i++) {
                // 删除子文件
                if (files[i].isFile()) {
                    flag = deleteFile(files[i].getAbsolutePath());
                    if (!flag)
                        break;
                }
                // 删除子目录
                else if (files[i].isDirectory()) {
                    flag = deleteDirectory(files[i]
                            .getAbsolutePath());
                    if (!flag)
                        break;
                }
            }
        }
        if (!flag) {
            log.info("删除目录失败！");
            return false;
        }
        // 删除当前目录
        if (dirFile.delete()) {
            log.info("删除目录" + dir + "成功！");
            return true;
        } else {
            return false;
        }
    }

    //base64上传文件
    public static String uploadBase64(String base64) {
        DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        DateFormat dfT = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = Calendar.getInstance();
        String realPath = UploadConfig.REAL_PATH + "/" + dfT.format(calendar.getTime());
        File targetFile = new File(realPath);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
        String fileName = df.format(calendar.getTime()) + ((int) (Math.random() * 9000) + 1000) + ".jpg";
        try {
            Files.write(Paths.get(realPath + "/" + fileName), Base64.decodeBase64(base64.substring(base64.indexOf(",") + 1)), StandardOpenOption.CREATE);
            return "/" + UploadConfig.VIRTUAL_PATH + "/" + dfT.format(calendar.getTime()) + "/" + fileName;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将Excel解析成list
     *
     * @param excelFile
     * @return
     */
    public static List<List<String>> excelToList(MultipartFile excelFile) {
        List<List<String>> list = new ArrayList<>();
        Workbook workbook;
        try {
            InputStream inputStream = excelFile.getInputStream();
            workbook = WorkbookFactory.create(inputStream);
            inputStream.close();
            //工作表对象
            Sheet sheet = workbook.getSheetAt(0);
            //总行数
            int rowLength = sheet.getLastRowNum();
            if (rowLength > 0) {
                //工作表的列
                Row row = sheet.getRow(0);
                //总列数
                int cellLength = row.getLastCellNum();
                //得到指定的单元格
                Cell cell;
                for (int i = 0; i <= rowLength; i++) {
                    int count = 0;
                    row = sheet.getRow(i);
                    List<String> rowList = new ArrayList<>();
                    for (int j = 0; j < cellLength; j++) {
                        cell = row.getCell(j);
                        if (ObjectUtils.isEmpty(cell)) {
                            rowList.add("");
                            count++;
                        } else {
                            cell.setCellType(CellType.STRING);
                            if (StringUtils.isBlank(cell.getStringCellValue().trim())) {
                                rowList.add("");
                                count++;
                            } else {
                                rowList.add(cell.getStringCellValue().trim());
                            }
                        }
                    }
                    //如果所有的列都不为空则是有效数据
                    if (cellLength != count) {
                        list.add(rowList);
                    }
                }
            }
        } catch (Exception e) {
            log.error("parse excel file error :", e);
        }
        return list;
    }

    /**
     * 通用下载Excel格式文件的方法
     *
     * @param response
     * @param title      文件名称
     * @param headTitles 文件表头
     * @param data       文件数据
     * @throws IOException
     */
    public static void exportExcel(HttpServletResponse response, String title, LinkedHashMap<String, String> headTitles, List<Map<String, Object>> data) {
        //创建HSSFWorkbook对象(excel的文档对象)
        HSSFWorkbook wb = new HSSFWorkbook();
        //建立新的sheet对象（excel的表单）
        HSSFSheet sheet = wb.createSheet(title);
        sheet.setDefaultColumnWidth(15);
        //设置字体
        HSSFFont font = wb.createFont();
        font.setFontName("黑体");
        //表头
        HSSFRow rowtitle = sheet.createRow(0);
        int titlecount = 0;
        for (Map.Entry<String, String> entry : headTitles.entrySet()) {
            if (titlecount < headTitles.size()) {
                rowtitle.createCell(titlecount).setCellValue(entry.getValue());
                titlecount++;
            }
        }
        int datacount = 0;
        for (int i = 0; i < data.size(); i++) {
            HSSFRow row = sheet.createRow(datacount + 1);
            int rowcount = 0;
            for (Map.Entry<String, String> entry : headTitles.entrySet()) {
                if (rowcount < headTitles.size()) {
                    row.createCell(rowcount).setCellValue(StringUtil.isNumber(
                            data.get(i).get(entry.getKey()) == null ? StringUtils.EMPTY : data.get(i).get(entry.getKey()).toString()
                    ));
                    rowcount++;
                }
            }
            datacount++;

        }
        try {
            //输出Excel文件
            OutputStream output = response.getOutputStream();
            response.reset();
            response.setHeader("Content-disposition", "attachment; filename=" + new String(title.getBytes("UTF-8"), "ISO-8859-1") + ".xls");
            response.setContentType("application/msexcel");
            response.setCharacterEncoding("UTF-8");
            wb.write(output);
            output.close();
        } catch (Exception e) {
            log.error("export excel file error :", e);
        }
    }
}
